package com.atguigu.jinx.conf;

import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.ScheduledUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import lombok.Data;
import lombok.SneakyThrows;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import java.io.FileInputStream;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;


/**
 * @author kuanggong
 */
@Configuration
@PropertySource("classpath:wxpay.properties")
@ConfigurationProperties(prefix = "wxpay")
@Data
public class WxPayConfig {

    /**
     * 商户号
     */
    private String mchId;

    /**
     * 商户API整数序列号
     */
    private String mchSerialNo;

    /**
     * 商户私钥文件pem
     */
    private String privateKeyPath;

    /**
     * api v3秘钥
     */
    private String apiV3Key;

    /**
     * app_id
     */
    private String appid;

    /**
     * 微信服务器的地址
     */
    private String domain;

    /**
     * 微信支付回调地址
     */
    private String notifyDomain;

    @SneakyThrows
    public PrivateKey getPrivateKey(String fileName) {
        return PemUtil.loadPrivateKey(new FileInputStream(fileName));
    }

    /**
     * 获取签名验证器
     *
     * @return
     */
    @Bean
    public ScheduledUpdateCertificatesVerifier getVerifier() {
        return new ScheduledUpdateCertificatesVerifier(
                new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, getPrivateKey(privateKeyPath))),
                apiV3Key.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 获取签名验证器请求对象
     * 使用@Bean注解可以在应用程序启动的时候直接自动创建出来,无需我们做更多的传输配置才能够使用。
     *
     * @param verifier
     * @return
     */
    @Bean("getWxPayClient")
    public CloseableHttpClient getWxPayClient(ScheduledUpdateCertificatesVerifier verifier) {
// 使用定时更新的签名验证器，不需要传入证书
        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                .withMerchant(mchId, mchSerialNo, getPrivateKey(privateKeyPath))
                .withValidator(new WechatPay2Validator(verifier));
// 通过WechatPayHttpClientBuilder构造的HttpClient，会自动的处理签名和验签，并进行证书自动更新
        CloseableHttpClient httpClient = builder.build();
        return httpClient;
    }

}
